<?php

namespace App\Http\Services\Api\V1\App\Customer;

use App\Http\Controllers\Api\V1\App\Customers\ThirdPartyLoginController;
use App\Models\Customers\WechatUser;
use App\Models\Setting;
use App\Services\Utils\ApiChecker;
use GuzzleHttp\Exception\GuzzleException;
use Laravel\Socialite\Facades\Socialite;

class WechatService
{
    use ApiChecker;

    const OAUTH_TYPE_WECHAT_APP = 'wechat_app';
    const KEY_OAUTH_WECHAT_APP_APP_ID = 'oauth_wechat_app_app_id';
    const KEY_OAUTH_WECHAT_APP_APP_SECRET = 'oauth_wechat_app_app_secret';

    public function setWechatConfig()
    {
        $clientId = Setting::getSettingSpecifyValue(self::KEY_OAUTH_WECHAT_APP_APP_ID);
        $clientSecret = Setting::getSettingSpecifyValue(self::KEY_OAUTH_WECHAT_APP_APP_SECRET);
        $redirectUrl = "http://dw-api.me/api/redirect";
        $config = new \SocialiteProviders\Manager\Config($clientId, $clientSecret, $redirectUrl);

        return $config;
    }

    /**
     * @return \App\Models\Customers\Customer|array|\Illuminate\Database\Eloquent\Model|null|object
     * @throws \Exception
     */
    public function handleWechatCallback()
    {
        // 设置配置文件
        $config = $this->setWechatConfig();

        // laravel/socialite 请求的认证
        session(['state' => 890]);
        request()->offsetSet('state', 890);

        try {
            $res =  Socialite::driver('weixin')->setConfig($config)->user();
            $user = $res->user;
        } catch (\Exception $e){
            logger($e->getMessage());
            $this->checkIsTrue(false, trans('customer.wechat_oauth_error'));
        }

        $wechat_data = $this->assembleWechatUser($user);
        $wechat_user = $this->updateOrCreateUser($wechat_data);
        $oauth_type = self::OAUTH_TYPE_WECHAT_APP;

        $user = (new ThirdPartyService)->generateUser($wechat_user, $oauth_type);

        return $user;
    }

    /**
     * @param array $user
     * @return array
     */
    public function assembleWechatUser(array $user)
    {
        $wechat_user_data = [
            'openid'           => $user['openid'],
            'unionid'          => $user['unionid'],
            'nickname'         => $user['nickname'],
            'nickname_unicode' => json_encode($user['nickname']),
            'sex'              => $user['sex'],
            'language'         => $user['language'],
            'city'             => $user['city'],
            'province'         => $user['province'],
            'country'          => $user['country'],
            'headimgurl'       => $user['headimgurl'],
        ];

        return $wechat_user_data;

    }

    /**
     * @param array $wechat_user_data
     * @return WechatUser
     */
    public function updateOrCreateUser(array $wechat_user_data)
    {
        if ($unionid = $wechat_user_data['unionid'] ?? null) {
            $customer_id = (new WechatUser)->where('unionid', $unionid)
                ->where('customer_id', '<>', WechatUser::WECHAT_USER_CUSTOMER_ID_DEFAULT)
                ->first()
                ->customer_id ?? WechatUser::WECHAT_USER_CUSTOMER_ID_DEFAULT;

            $wechat_user_data['customer_id'] = $customer_id;
        }

        /** @var WechatUser $wechat_user */
        $wechat_user = (new WechatUser)->updateOrCreate (
            ['openid' => $wechat_user_data['openid']], $wechat_user_data
        );

        return $wechat_user;
    }
}